package com.example.util;

import java.util.*;

public class TreeUtils {

    /**
     * 树的工具类
     * @param id       主键id
     * @param pid      父主键id
     * @param child    子字段
     * @param obj      数据列表
     * @return
     */
    public static List<Map<String,Object>> listToTree(String id, String pid, String child, List<Map<String,Object>> obj){
        if(obj==null){
            return Collections.emptyList();
        }
        //先找出最顶层的
        List<Map<String,Object>> mapLists=new ArrayList<>();
        for (Map<String,Object> map: obj ) {
            Object parentValue=map.get(pid);
            boolean flag=true;
            for (Map<String,Object> mapList: obj ) {
                Object childValue=mapList.get(id);
                if(Objects.equals(parentValue,childValue)){
                    flag=false;
                }
            }
            if(flag){
                mapLists.add(map);
            }
        }
        List<Map<String,Object>> parents=new ArrayList<>();
        //遍历父
        for (Map<String,Object> map: mapLists ) {
            List<Map<String,Object>> mapList=childListToTree(id,pid,child,map,obj);
            map.put(child,mapList);
            parents.add(map);
        }
        return parents;
    }

    private static List<Map<String,Object>> childListToTree(String id,String pid,String child,Map<String,Object> obj,List<Map<String,Object>> mapList){
        if(mapList==null){
            return Collections.emptyList();
        }
        Object parentValue=obj.get(id);
        List<Map<String,Object>> childList=new ArrayList<>();
        for (Map<String, Object> map : mapList) {
            Object childValue=map.get(pid);
            if(Objects.equals(parentValue,childValue)){
                List<Map<String,Object>> list=childListToTree(id,pid,child,map,mapList);
                map.put(child,list);
                childList.add(map);
            }
        }
        return childList;
    }

    /**
     * 通过某个个字段，过滤树里面一些不必要的数据
     * @param field
     * @param value
     * @param treeList
     * @return
     */
    public static List<Map<String,Object>> treeFilterFields(String field,Object value,String child,List<Map> treeList){
        List<Map<String, Object>> array=new ArrayList<>();
        for (Map<String, Object> map : treeList) {
            Object val=map.get(field);
            if(Objects.equals(val,value)){
                Map<String, Object> m = new HashMap<>(map);
                m.remove(child);
                array.add(m);
            }else {
                Object list=map.get(child);
                if(list instanceof List){
                    List<Map<String,Object>> listTree=(List<Map<String, Object>>) list;
                    List<Map<String,Object>> childTree=childTreeFilterFields(field,value,child,listTree);
                    if(childTree.size() > 0){
                        Map<String, Object> m = new HashMap<>(map);
                        m.put(child,childTree);
                        array.add(m);
                    }
                }
            }
        }
        return array;
    }


    private static List<Map<String,Object>> childTreeFilterFields(String field,Object value,String child,List<Map<String,Object>> treeList){
        if(treeList==null || treeList.size() == 0){
            return Collections.emptyList();
        }
        List<Map<String, Object>> array=new ArrayList<>();
        for (Map<String, Object> map : treeList) {
            Object val=map.get(field);
            if(Objects.equals(val,value)){
                Map<String, Object> m = new HashMap<>(map);
                array.add(m);
            }else {
                Object list=map.get(child);
                if(list instanceof List){
                    List<Map<String,Object>> listTree=(List<Map<String, Object>>) list;
                    List<Map<String,Object>> childTree=childTreeFilterFields(field,value,child,listTree);
                    if(childTree.size() > 0){
                        Map<String, Object> m = new HashMap<>(map);
                        m.remove(child);
                        m.put(child,childTree);
                        array.add(m);
                    }
                }
            }
        }
        return array;
    }


    /**
     * 将树在转为list数据,
     * 应用于对接某些前端框架已经写好的菜单demo数据
     * @param child  子的字段
     * @param maps   数据列表
     * @return
     */
    public static List<Map<String,Object>> treeToList(String child,List<Map> maps){
        List<Map<String,Object>> arr=new ArrayList<>();
        for (Map<String, Object> map : maps) {
            if(map.get(child)!=null){
                Object val=map.get(child);
                if(val instanceof List){
                    List<Map<String, Object>> arrList=(List<Map<String, Object>>)val;
                    treeChildToList(child,arrList,arr);
                }
            }
            map.remove(child);
            arr.add(map);
        }
        return arr;
    }

    private static void treeChildToList(String child,List<Map<String,Object>> maps,List<Map<String,Object>> arr){
        if(maps.size()<=0){
            return;
        }
        for (Map<String, Object> map : maps) {
            if(map.get(child)!=null){
                Object val=map.get(child);
                if(val instanceof List){
                    List<Map<String, Object>> arrList=(List<Map<String, Object>>)val;
                    treeChildToList(child,arrList,arr);
                }
            }
            map.remove(child);
            arr.add(map);
        }
    }
}
